﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using snat.algorithms.Monitors.MessageTime;
using snat.model;
using System.Diagnostics;

namespace snat.algorithms.Monitors.MessageCount
{
    /// <summary>
    /// MessageCounter is a simple predicate monitor which matches every
    /// n messages, where n is specified by the _period constructor parameter
    /// </summary>
    public class MessageCounter : PredicateMonitor
    {
        /// <summary>
        /// Fires every Period messages sent.
        /// </summary>
        public event AlgorithmProcessed Process;

        /// <summary>
        /// The number of messages to wait until firing.
        /// </summary>
        public int Period{
            get;
            private set;
        }

        /// <summary>
        /// The number of messages sent in the current period
        /// </summary>
        public int Count {
            get;
            private set;
        }


        /// <summary>
        /// Very simple constructor; only sets the value of Period
        /// </summary>
        /// <param name="_period">The length of the period to wait before firing</param>
        public MessageCounter(int _period) {
            Debug.Assert(_period > 0);
            //should be this i think todo
            //if (_period <= 0) throw new ArgumentOutOfRangeException("_period", _period, "The period for this must be greater than 0");
            Period = _period;
        }


        /// <summary>
        /// The algorithm name.
        /// </summary>
        public string Name {
            get { return "GlobalMessageCount predicate monitor, period " + Period; }
        }

        /// <summary>
        /// Increments the Count property and compares this value to the window length.
        /// If they are equal, it fires the event and resets Count.
        /// </summary>
        /// <param name="dummy">The message. This is ignored.</param>
        public void OnMessage(Message dummy) {
            Count++;
            if (Count == Period) {
                if (Process != null) Process(this);
                Count = 0;
            }
        }

        public void Register() {
            NetworkModel.Instance.MessageProcessed += OnMessage;
        }

        public void DeRegister() {
            NetworkModel.Instance.MessageProcessed -= OnMessage;
        }
    }
}
